/*
 *  ui系统的根目录,整个系统均由view单元组成
 *  使用流程:
 *    0.装载ttf字体: FontLoad(VFT_DEFAULT, "xxx.ttf");
 *    1.编辑配置: ViewInfo info;
 *    2.初始化: View* v = new View(info);
 *    3.帧渲染: v->Render(screen);
 *    4.帧延时: usleep(100000);
 *  特性:
 *    1.完全赋值式初始化
 *    2.统一格式的回调函数
 *    3.被显示期间,每个控件拥有自己的图层内存,用于独立刷新
 *    4.被隐藏或窗口关闭时,释放控件图层内存
 *    5.实际ui可小于屏幕分辨率,最终输出通过拉伸图像(节省内存)
 */
#ifndef _VIEW_H_
#define _VIEW_H_

#include "view_info.h"
#include "crosslist.h"
#include "image.h"

#include <iostream>
using namespace std;

/* 控件单元,也是整个ui系统的结构 */
class View : public CrossList
{
public:
    /* ----- 初始化参数配置,赋值式初始化 ----- */
    ViewInfo m_info;

public:
    /* ----- 构造 ----- */
    View();
    View(const ViewInfo& info);
    ~View();

    /* ----- 字体文件加载 ----- */

    /* 字体装载和释放,之后才能通过font使用指定字体 */
    static int32_t FontLoad(ViewFontType font, const char* fontFile);
    static int32_t FontUnLoad();

    /* ----- 渲染接口 ----- */

    /* 一帧渲染,可选择渲染到 screenImage 指定位置或者后续通过 GetImage() 获得图像 */
    int32_t Render(
        Image* screenImage = NULL,
        int32_t x = 0, /* 把 view 绘制到屏幕 x,y 位置 */
        int32_t y = 0);

    /* ----- 参数查询 ----- */

    /* 实际的控件范围 */
    int32_t GetX();
    int32_t GetY();
    int32_t GetWidth();
    int32_t GetHeight();

    /* 读取内存 */
    ImageGrid& GetImageGrid();

    /* ----- 链表控制和查询 ----- */

    /* 插入子控件到序号index位置,序号从0数起 */
    int32_t ChildInsert(const ViewInfo& info, int32_t index);
    int32_t ChildInsert(View* view, int32_t index); /* 完全接管view指针内存 */
    /* 添加子控件到队尾,front=true时添加到队首 */
    int32_t ChildAdd(const ViewInfo& info, bool front = false);
    int32_t ChildAdd(View* view, bool front = false); /* 完全接管view指针内存 */
    /* 从队列移除并释放内存 */
    int32_t ChildRemove(int32_t index);
    /* 交换位置 */
    int32_t ChildSwap(int32_t index1, int32_t index2);

    /* 同级控件查找 */
    View* Parent();
    View* Prev();
    View* Next();
    int32_t Index();
    View* At(int32_t index);

    /* 子控件查找 */
    int32_t ChildNum();
    View* ChildBegin();
    View* ChildEnd();
    View* ChildAt(int32_t index);

    /* ----- 事件传递 ----- */

    /* 发起事件回调,xy为坐标 */
    int32_t OnCallback(ViewCallbackType type, int32_t x = 0, int32_t y = 0);

    /* ----- 状态查询 ----- */

    /* 检测坐标命中 */
    bool IsClickHit(int32_t x, int32_t y);
    /* 通过和父控件比较resizeFlag判断是否需要重新计算位置范围 */
    bool IsNeedResize();
    /* 通过infoCrc32判断是否需要重新绘图 */
    bool IsNeedRedraw();

    /* 位置范围更新标志(系统调用) */
    uint32_t GetResizeFlag();

private:
    /* 实际的控件范围 */
    int32_t m_shapeX, m_shapeY;
    int32_t m_shapeWidth, m_shapeHeight;

    /* 文本在控件内左上角偏移和大小 */
    int32_t m_textXErr, m_textYErr;
    int32_t m_textWidth, m_textHeight;

    /* 用于检查info是否发生更改,以判断是否需要重新绘图 */
    uint32_t m_infoCrc32;
    /* 通过和父控件比较resizeFlag判断当前是否需要重新计算位置范围 */
    uint32_t m_resizeFlag;

    /* 控件图层,非常驻内存,在窗口被关闭或隐藏时释放 */
    ImageGrid m_imageGrid;

private:
    /* 重置默认配置 */
    void Default();

    /* ----- 事件回调处理,定义在 view_callback.cpp ----- */

    /* 事件分类处理 */
    int32_t CallbackClick(ViewCallbackType type, int32_t x, int32_t y);
    int32_t CallbackZoom(ViewCallbackType type, int32_t x, int32_t y);
    int32_t CallbackState(ViewCallbackType type);
    int32_t CallbackRelease(ViewCallbackType type);

    /* 显示状态变化和绘图事件 */
    int32_t ActiveDisplay(bool yes);
    int32_t ActiveDraw();
    /* 焦点变动 */
    int32_t ActiveFocusIn(bool yes);
    /* 缩放: >0/放大 <0/缩小 */
    int32_t ActiveZoom(int32_t zoom);
    /* 位置范围更新计算 */
    int32_t ActiveResize();

    /* ----- 位置范围计算,定义在 view_relative.cpp ----- */

    /* 计算形状和文字输出位置范围 */
    int32_t Resize();
    int32_t ResizeText(bool autoWidth, bool autoHeight, bool centerX, bool centerY);

    /* ----- 绘图实现,定义在 view_shape.cpp ----- */

    /* 控件绘图顺序为: 形状->图片->文字 */
    int32_t Draw();
    int32_t DrawShape();
    int32_t DrawPicture();
    int32_t DrawText();
};

#endif // _VIEW_H_
